
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>WebSocket 与 HTTP 的区别 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>WebSocket 与 HTTP 的区别 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">HTTP 和 WebSocket 在通信模式和连接类型上的核心区别是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">HTTP 是一种基于“请求-响应”模式的单向通信协议，以短连接为主，每次通信都需要客户端发起请求。而 WebSocket 是一种全双工的双向通信协议，建立的是持久性的长连接，允许服务器和客户端随时主动发送消息。</div>
          </div>
          <div class="card-source">来源: 基础概念对比 - 核心差异</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">WebSocket 是如何建立连接的？请描述其握手和协议升级过程。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">WebSocket 依赖 HTTP 协议完成初始握手。客户端首先发送一个标准的 HTTP 请求，其中包含 `Upgrade: websocket` 和 `Connection: Upgrade` 两个关键头部，请求将协议升级。服务器若同意升级，会返回状态码为 `101 Switching Protocols` 的响应，此后双方的通信协议便从 HTTP 切换为 WebSocket，并保持长连接。</div>
          </div>
          <div class="card-source">来源: 协议级别的区别 - 1. 建立连接的过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">相较于HTTP，WebSocket 在数据传输效率方面有何优势？它的数据传输基本单元是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">WebSocket 的主要优势在于其较低的传输开销。HTTP 每次通信都需要发送完整的请求头，开销较大。而 WebSocket 在初始握手后，后续通信仅传输包含极少元信息的数据帧，极大地减少了网络负载和冗余。其数据传输的基本单元是“帧”（Frame）。</div>
          </div>
          <div class="card-source">来源: 协议级别的区别 - 4. 数据传输效率</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">应用</div>
          <div class="card-question">请列举至少三种适合使用 WebSocket 的典型应用场景。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">应用</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">适合使用 WebSocket 的典型场景包括：1. 实时聊天应用；2. 在线协作工具（如多人实时编辑文档）；3. 金融数据推送（如股票行情）；4. 多人在线游戏；5. 直播弹幕系统等需要高实时性交互的应用。</div>
          </div>
          <div class="card-source">来源: 应用场景 - 1. WebSocket 的应用场景</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">为什么说 HTTP 是“无状态”协议，而 WebSocket 是“有状态”协议？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">HTTP 被认为是“无状态”的，因为它的每次请求都是独立的，服务器不会保存之前请求的状态，需要借助 Cookies 或 Session 等机制来维持用户会话。相比之下，WebSocket 是“有状态”的，因为一旦连接建立，该连接会持续存在，通信双方可以在这个连接上维持上下文信息，无需重复建立会话状态。</div>
          </div>
          <div class="card-source">来源: 协议级别的区别 - 3. 状态性</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">安全</div>
          <div class="card-question">在WebSocket的握手过程中，`Sec-WebSocket-Key` 和 `Sec-WebSocket-Accept` 这两个头部字段起到了什么安全作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">安全</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">这两个字段用于安全校验，确保握手未被篡改。客户端发送一个由 Base64 编码的随机值 `Sec-WebSocket-Key`。服务器接收后，将这个值与一个固定的 GUID 拼接，进行 SHA-1 哈希计算并再次 Base64 编码，生成 `Sec-WebSocket-Accept` 返回给客户端。客户端通过验证这个返回值来确认服务器的合法性。</div>
          </div>
          <div class="card-source">来源: 握手与协议升级 - 3. 安全校验机制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">WebSocket 的数据传输基本单元“帧”（Frame）包含哪些关键信息？其中“操作码 (Opcode)”的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">WebSocket 的数据帧结构包含：FIN 位（标记是否为消息的最后一帧）、操作码（Opcode）、掩码（Mask）、数据长度和负载数据。其中，“操作码 (Opcode)” 的作用是指定帧的类型，例如文本帧、二进制帧或关闭帧等。</div>
          </div>
          <div class="card-source">来源: 数据格式与传输 - 2. WebSocket 数据传输</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">安全</div>
          <div class="card-question">WebSocket 的持久连接特性带来了哪些HTTP不常见的安全风险？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">安全</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">WebSocket 的持久连接特性带来了几个独特的安全风险：1. 连接劫持：长连接为攻击者提供了更长的攻击窗口。2. 资源耗尽攻击：攻击者可以通过创建大量持久连接来耗尽服务器资源。3. 跨站请求伪造（CSRF）：攻击者可能利用现有认证信息伪造连接请求。</div>
          </div>
          <div class="card-source">来源: 安全性 - 2. WebSocket 的安全性挑战</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">应用</div>
          <div class="card-question">在一个复杂的电子商务平台中，HTTP 和 WebSocket 通常如何结合使用以发挥各自的优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">应用</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在电子商务平台中，两者通常结合使用。HTTP 用于处理请求-响应模式的业务，如商品列表加载、订单提交和用户管理。而 WebSocket 则用于需要实时推送的场景，例如实时更新订单状态、库存变化通知给客户端。</div>
          </div>
          <div class="card-source">来源: 应用场景 - 4.1 混合场景</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
